import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseListener;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.ActionEvent;
import java.awt.Point;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;


public class DrwPlgn extends JPanel
{

  final     int INTERVAL   =    3;
  final     int MAXIMUM    = 1000;

  private   int width;
  private   int height;
  private   int delay;

  private   int[] xCoords1    = new int[ MAXIMUM];
  private   int[] yCoords1    = new int[ MAXIMUM];
  private   int   nmbrPnts1   = 0;
  
  private   int[] xCoords2    = new int[ MAXIMUM];
  private   int[] yCoords2    = new int[ MAXIMUM];
  private   int   nmbrPnts2   = 0;

  private   int[] xCoords     = new int[ MAXIMUM];
  private   int[] yCoords     = new int[ MAXIMUM];
  private   int   nmbrPnts    = 0;

  private   int[] xMoves      = new int[ MAXIMUM];
  private   int[] yMoves      = new int[ MAXIMUM];
  
  private   boolean afterFirst = false;
  private   boolean building1 = true;
  private   boolean building2 = false;

  private   static boolean fromFile = false;
  private   static boolean animate = false;
  private   static double  t = 0.0, dt = 0.03;
  private   static String  sfilename, tfilename;

  private   Timer tmr;

  public DrwPlgn ( int wdth, int hght, int dly)
  {
    width  = wdth;
    height = hght;
    delay  = dly;
    tmr    = new Timer( delay, new TimerListener());
    addMouseListener( new msLstnr());
    setPreferredSize( new Dimension( width, height));
  }

  public void paintComponent ( Graphics page)
  {
    page.setColor( Color.black);
    page.fillRect( 0, 0, width, height);
    page.setColor( Color.green);
   	page.drawPolyline( xCoords1, yCoords1, nmbrPnts1);
   	page.drawPolyline( xCoords2, yCoords2, nmbrPnts2);
    if (animate)
    {
	    page.setColor( Color.red);
	    page.drawPolyline( xCoords, yCoords, nmbrPnts1);
    }
  }

  public static void main ( String[] arguments)
  {
    JFrame plgnFrame;
    DrwPlgn plgnPanel;
    int wdth, hght, delay;

    if (arguments.length >= 3)
    {
	    wdth      = Integer.parseInt( arguments[0]);
        hght      = Integer.parseInt( arguments[1]);
        delay     = Integer.parseInt( arguments[2]);
	    if (arguments.length == 5)
    	{
	    	sfilename = arguments[3];
	    	tfilename = arguments[4];
	    	fromFile = true;
    	}
        plgnFrame = new JFrame( "Morph a Polygon");
        plgnPanel = new DrwPlgn( wdth, hght, delay);
        plgnFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
        plgnFrame.getContentPane().add( plgnPanel);
        plgnFrame.pack();
        plgnFrame.setVisible( true);
    }
    else
    {
	    System.out.println( "Usage is\n  java DrwPlgn <width> <height> <delay> [<source> <target>]");
    }
  }

  private void interpolate(double t)
  {
	  for (int i = 0; i < nmbrPnts1; i++)
	  {
		  xCoords[i] = (int) ((double) xCoords1[i] + t * (double) ((xCoords2[i] - xCoords1[i])));
		  yCoords[i] = (int) ((double) yCoords1[i] + t * (double) ((yCoords2[i] - yCoords1[i])));
	  }
  }
  
  private void loadPoly(String filename, boolean sflag)
  {
	BufferedReader in = null;
	try 
	{
		in = new BufferedReader(new FileReader(filename));
    	String line;
    	line = in.readLine();
    	int numpts = Integer.parseInt(line);
    	for (int i = 0; i < numpts; i++)
   		{
	    	line = in.readLine();
	    	String nums[] = line.split(" ");
	    	if (sflag)
	    	{
		    	xCoords1[i] = Integer.parseInt(nums[0]);
		    	yCoords1[i] = Integer.parseInt(nums[1]);
	   	 	}
	    	else
	   	 	{
		    	xCoords2[i] = Integer.parseInt(nums[0]);
		    	yCoords2[i] = Integer.parseInt(nums[1]);
	    	}
    	}
    	if (sflag)
    	{
	    	nmbrPnts1 = numpts;
	    	xCoords1[nmbrPnts1] = xCoords1[0];
	    	yCoords1[nmbrPnts1++] = yCoords1[0];
    	}
    	else
    	{
	    	nmbrPnts2 = numpts;
	    	xCoords2[nmbrPnts2] = xCoords2[0];
	    	yCoords2[nmbrPnts2++] = yCoords2[0];
    	}
    	in.close();
	}
	catch (IOException e) 
	{
	   	System.out.println(e);
	}
  }
  
  
  private class msLstnr implements MouseListener
  {
    public void mouseClicked ( MouseEvent msEvnt) 
    {
	}

    public void mouseEntered ( MouseEvent msEvnt)
    {
      tmr.stop();
      t = 0.0;
      animate = false;
    }

    public void mouseExited  ( MouseEvent msEvnt)
    {
	  animate = true;
	  for (int i = 0; i < nmbrPnts1; i++)
	  {
		  xCoords[i] = xCoords1[i];
		  yCoords[i] = yCoords1[i];
	  }		  
	  repaint();
      tmr.start();
    }

    public void mousePressed ( MouseEvent msEvnt)
    {
      Point clicked = msEvnt.getPoint();
      int[] newXs, newYs;
      int   coord;

      if (fromFile)
      {
	      building1 = building2 = false;
	      loadPoly(sfilename, true);
	      loadPoly(tfilename, false);
	      repaint();
      }
      else if (building1)
      {
	      if (afterFirst && xCoords1[ 0] - INTERVAL < clicked.x && clicked.x < xCoords1[ 0] + INTERVAL
                         && yCoords1[ 0] - INTERVAL < clicked.y && clicked.y < yCoords1[ 0] + INTERVAL)
          {
	          building1 = false;
	          building2 = true;
              xCoords1[ nmbrPnts1]   = clicked.x;
              yCoords1[ nmbrPnts1++] = clicked.y;
              repaint();
          }
          else
          {
              xCoords1[ nmbrPnts1]   = clicked.x;
              yCoords1[ nmbrPnts1++] = clicked.y;
              if (afterFirst)
              {
	              repaint();
              }
              else
              {
	              afterFirst = true;
              }
          }
      }
      else if (building2)
      {
	      if (afterFirst && xCoords2[ 0] - INTERVAL < clicked.x && clicked.x < xCoords2[ 0] + INTERVAL
                         && yCoords2[ 0] - INTERVAL < clicked.y && clicked.y < yCoords2[ 0] + INTERVAL)
          {
	          building2 = false;
              xCoords2[ nmbrPnts2]   = clicked.x;
              yCoords2[ nmbrPnts2++] = clicked.y;
              repaint();
          }
          else
          {
              xCoords2[ nmbrPnts2]   = clicked.x;
              yCoords2[ nmbrPnts2++] = clicked.y;
              if (afterFirst)
              {
	              repaint();
              }
              else
              {
	              afterFirst = true;
              }
          }
      }
      else
      {
      }
    }

    public void mouseReleased ( MouseEvent msEvnt)
    {
    }
  }

  
  private class TimerListener implements ActionListener
  {
    public void actionPerformed ( ActionEvent actnEvnt)
    {
	    t += dt;
	    if (t < 0.9999)
	    {
		    interpolate(t);
	    }
	    repaint();
     }
  }
}